package com.mwm.loyal.util;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.mwm.loyal.bean.ResultBean;
import com.mwm.loyal.gson.TypeBuilder;
import com.mwm.loyal.gson.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GsonUtil {
    private static final Gson gson = new Gson();

    public static <T> Map<String, T> json2Map(String result) {
        Map<String, T> map = new HashMap<>();
        if (null == result)
            return map;
        map = gson.fromJson(result, new TypeToken<HashMap<String, T>>() {
        }.getType());
        return map;
    }

    public static <T> List<T> json2List(String json, Class<T> tClass) {
        List<T> list = new ArrayList<>();
        try {
            if (json.isEmpty()) {
                return list;
            }
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for (JsonElement elem : array) {
                list.add(gson.fromJson(elem, tClass));
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return list;
        }
    }

    /**
     * @param objClass 父类里面的范型
     */
    public static <O> ResultBean<O, List<?>> json2Obj(String json, Class<O> objClass) {
        Type type = TypeBuilder
                .newInstance(ResultBean.class)
                .addTypeParam(objClass)
                .build();
        return gson.fromJson(json, type);
    }

    public static <O, A> ResultBean<O, List<A>> jsonTest(String json, Class<O> objClass, Class<A> aClass) {
        if (null == json)
            return null;
        TypeBuilder typeBuilder = TypeBuilder
                .newInstance(ResultBean.class);
        if (json.contains("\"obj\":")) {
            typeBuilder.addTypeParam(objClass)
                    .beginSubType(List.class)
                    .addTypeParam(aClass)
                    .endSubType();
        } else if (json.contains("\"list\":")) {
            typeBuilder.beginSubType(List.class)
                    .addTypeParam(aClass)
                    .endSubType()
                    .addTypeParam(objClass);
        }
        return gson.fromJson(json, typeBuilder.build());
    }

    /**
     * {@link #json2Obj(String, Class)}
     *
     * @param aClass 父类里面的范型
     */
    public static <A> ResultBean<?, List<A>> json2ObjArray(String json, Class<A> aClass) {
        Type type = TypeBuilder
                .newInstance(ResultBean.class)
                .beginSubType(List.class)
                .addTypeParam(aClass)
                .endSubType()
                .build();
        return gson.fromJson(json, type);
    }

    public static <T> T json2Bean(String json, Class<T> tClass) {
        return gson.fromJson(json, tClass);
    }

    public static <T> List<T> json2BeanList(String json, Class<T> tClass) {
        List<T> list = new ArrayList<>();
        try {
            if (TextUtils.isEmpty(json)) {
                return list;
            }
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for (JsonElement elem : array) {
                list.add(gson.fromJson(elem, tClass));
            }
            return list;
        } catch (Exception e) {
            list.clear();
            return list;
        }
    }

    public static String obj2Json(Object object) {
        if (null == object)
            return "{}";
        return gson.toJson(object);
    }

    public static String list2Json(Object object) {
        if (null == object)
            return "[]";
        return gson.toJson(object);
    }
}